#测试 类成员函数的存储与调用

class memberClass(object):
                       # 类成员变量，不放在成员方法中，可通过类共享
                       # 可认为 伪静态变量，在类里，不实例化也可使用
    __m_number = 0     # 通过类名或类方法访问，实例化对象均会复制一份不影响类本身
    age = 0            # 变量前加双下划线为私有变量
    height = 0         # 注意，伪静态变量可由类名直接调用，只能类上访问修改
    testself  = 12     # 实例化对象均访问的是自身复制的那一份，无法共享

    def __init__(self,age = 0,height = 0,number = 0) -> None:
        
        self.age = age         # 定义的普通成员变量
        self.height = height 
        self.__m_number = number

    def addFun(self): #普通成员函数，类实例化后调用
                      #第一个位置参数(命名可变，常用self)默认指向调用对象，无法删除
                      #在不实例化类时调用可当作类函数，第一个位置参数不为对象
        return self.age + self.height + self.__m_number
    
    def addFun1(m,n):   #普通成员函数当类函数用法，只能在不实例化类时调用，
                        #不实例化意味着无法使用普通成员变量，但可访问静态变量
                        #实例化后第一个位置m即指向实例化对象，
                        #不管命名为何，第一位置即指向调用对象
        return m*n
    
    #真正的类函数，可通过对象和类调用，第一个位置参数(命名可变，常用cls)默认指向类本身
    @classmethod
    def song(cls):
        print('唱一首歌给类听:类方法',cls)
        cls.age = 30               #修改的是类成员变量，具有伪静态成员变量属性
        cls.testself = 11  

    #静态方法，对象和类调用
    @staticmethod
    def song_st():
        print('唱一首歌给类听:静态方法')
        print(memberClass.age)


def test_member():

    m1 = memberClass(15,130,1)  # 类实例化对象m1

    print(m1.addFun())   # 普通成员函数，类实例化后调用

    print(memberClass.addFun1(3,6))  # 普通成员函数当类函数用，在不实例化类时调用

    #print(m1.addFun1(1,6))  # 实例化后调用出错，此时m自动指向m1，入口参数变为一个
    #print(memberClass(15,130,2).addFun1(1,6))  # 以初始化方式实例化后调用也出错

    m1.song()
    memberClass.song()       # 真正的类函数，可通过实例化对象和类调用

    m1.song_st()
    memberClass.song_st()    # 静态方法，也可实例化对象和类调用

    print(memberClass.age)   # 通过类名调用伪静态变量
    print('****************')
    
    m2 = memberClass(10,131,12)  # 类实例化对象m2

    print(m2.addFun())
    print(m2.age,m2.height)

    print(memberClass.age,memberClass.height)   #看出类名调用的是静态变量

    m2.age = m2.age + 3            #修改m2的成员变量
    m2.height = m2.height + 1
    print(m2.addFun())
    print(m2.age,m2.height)

    print(memberClass.age,memberClass.height)  #静态变量没有改动，
                                     #表明实例化对象成员变量和静态变量不一样


    print(memberClass.testself)     #再测试一下只定义了静态变量的情况
    print(m2.testself)              #似乎可以通过对象访问静态变量
    m2.testself = 15                #但修改时发现只是复制了一份，并非访问原变量
    print(memberClass.testself)     #打印原静态变量并未被修改
    print(m2.testself)              #修改的是实例化对象复制的变量

    memberClass.testself = 13       #通过类名可访问该静态变量
    print(memberClass.testself)     #或使用类方法，静态方法

test_member()


